package com.codedancer.campus.client.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codedancer.campus.client.service.IDynamicCommentService;
import com.codedancer.campus.client.service.bo.dynamic.DynamicCommentAddBo;
import com.codedancer.campus.client.service.bo.dynamic.DynamicCommentPageSearchBo;
import com.codedancer.campus.client.service.vo.dynamic.DynamicCommentPageVo;
import com.codedancer.campus.common.exception.BusinessException;
import com.codedancer.campus.common.utils.UUIDGenerator;
import com.codedancer.campus.enums.DynamicStatus;
import com.codedancer.campus.mapper.DynamicCommentMapper;
import com.codedancer.campus.mapper.DynamicMapper;
import com.codedancer.campus.mapper.UserMapper;
import com.codedancer.campus.po.Dynamic;
import com.codedancer.campus.po.DynamicComment;
import com.codedancer.campus.po.User;
import com.codedancer.campus.qo.dynamic.DynamicCommentPageSearchQo;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class DynamicCommentServiceImpl implements IDynamicCommentService {

    @Autowired
    private DynamicCommentMapper dynamicCommentMapper;
    @Autowired
    private DynamicMapper dynamicMapper;
    @Autowired
    private UserMapper userMapper;

    /**
     * 新增评论
     *
     * @param dynamicCommentAddBo
     */
    @Override
    public void add(DynamicCommentAddBo dynamicCommentAddBo) {
        // 校验数据
        checkData(dynamicCommentAddBo);
        DynamicComment dynamicComment = BeanUtil
            .copyProperties(dynamicCommentAddBo, DynamicComment.class);
        dynamicComment.setCommentUserUuid(dynamicCommentAddBo.getCurrentUserUuid());
        dynamicComment.setUuid(UUIDGenerator.getUUID());
        dynamicComment.setDynamicUuid(dynamicCommentAddBo.getDynamicUuid());
        dynamicCommentMapper.insert(dynamicComment);
    }

    /**
     * 分页查询动态父级评论
     *
     * @param dynamicCommentPageSearchBo
     * @return
     */
    @Override
    public IPage<DynamicCommentPageVo> pageParentComment(
        DynamicCommentPageSearchBo dynamicCommentPageSearchBo) {
        DynamicCommentPageSearchQo dynamicCommentPageSearchQo = BeanUtil
            .copyProperties(dynamicCommentPageSearchBo, DynamicCommentPageSearchQo.class);
        IPage<DynamicComment> dynamicCommentIPage = dynamicCommentMapper.pageParentComment(
            new Page<DynamicComment>(dynamicCommentPageSearchBo.getPage(),
                dynamicCommentPageSearchBo.getSize()), dynamicCommentPageSearchQo);
        List<DynamicCommentPageVo> dynamicCommentPageVos;
        IPage<DynamicCommentPageVo> dynamicCommentPageVoIPage = new Page<>();
        dynamicCommentPageVos = dynamicCommentIPage.getRecords().stream().map(dynamicComment -> {
            DynamicCommentPageVo dynamicCommentPageVo = BeanUtil
                .copyProperties(dynamicComment, DynamicCommentPageVo.class);
            dynamicCommentPageVo.setCommentTime(dynamicComment.getCreateTime());
            // 查询评论人信息
            User commentUser = userMapper.selectById(dynamicComment.getCommentUserUuid());
            dynamicCommentPageVo.setCommentUserNickName(commentUser.getNickName());
            dynamicCommentPageVo.setCommentUserAvatar(commentUser.getAvatar());
            // 查询被回复人信息
            User repliedUser = userMapper.selectById(dynamicComment.getRepliedUserUuid());
            dynamicCommentPageVo.setRepliedNickName(repliedUser.getNickName());
            dynamicCommentPageVo
                .setHasChildren(dynamicCommentMapper.hasChildren(dynamicComment.getUuid()));
            return dynamicCommentPageVo;
        }).collect(Collectors.toList());
        dynamicCommentPageVoIPage.setRecords(dynamicCommentPageVos);
        dynamicCommentPageVoIPage.setTotal(dynamicCommentIPage.getTotal());
        return dynamicCommentPageVoIPage;
    }

    /**
     * 动态回复
     *
     * @param dynamicCommentAddBo
     */
    @Override
    public void reply(DynamicCommentAddBo dynamicCommentAddBo) {
        // 父级评论
        DynamicComment parentDynamicComment = dynamicCommentMapper
            .findById(dynamicCommentAddBo.getDynamicCommentUuid())
            .orElseThrow(() -> new BusinessException("动态评论不存在"));
        dynamicCommentAddBo.setDynamicUuid(parentDynamicComment.getDynamicUuid());
        checkData(dynamicCommentAddBo);
        if (dynamicCommentAddBo.getRepliedUserUuid()
            .equals(dynamicCommentAddBo.getCurrentUserUuid())) {
            throw new BusinessException("不能回复自己哦");
        }
        DynamicComment childrenDynamicComment = BeanUtil
            .copyProperties(dynamicCommentAddBo, DynamicComment.class);
        childrenDynamicComment.setDynamicUuid(parentDynamicComment.getDynamicUuid());
        childrenDynamicComment.setUuid(UUIDGenerator.getUUID());
        childrenDynamicComment.setCommentUserUuid(dynamicCommentAddBo.getCurrentUserUuid());
        childrenDynamicComment.setParentUuid(parentDynamicComment.getUuid());
        dynamicCommentMapper.insert(childrenDynamicComment);
    }

    /**
     * 分页查询该评论下子集评论
     *
     * @param dynamicCommentPageSearchBo
     * @return
     */
    @Override
    public IPage<DynamicCommentPageVo> pageChildrenComment(
        DynamicCommentPageSearchBo dynamicCommentPageSearchBo) {
        DynamicCommentPageSearchQo dynamicCommentPageSearchQo = BeanUtil
            .copyProperties(dynamicCommentPageSearchBo, DynamicCommentPageSearchQo.class);
        IPage<DynamicComment> dynamicCommentIPage = dynamicCommentMapper.pageChildrenComment(
            new Page<DynamicComment>(dynamicCommentPageSearchBo.getPage(),
                dynamicCommentPageSearchBo.getSize()), dynamicCommentPageSearchQo);
        IPage<DynamicCommentPageVo> dynamicCommentPageVoIPage = new Page<>();
        List<DynamicCommentPageVo> dynamicCommentPageVos;
        dynamicCommentPageVos = dynamicCommentIPage.getRecords().stream().map(dynamicComment -> {
            DynamicCommentPageVo dynamicCommentPageVo = BeanUtil.copyProperties(dynamicComment,
                DynamicCommentPageVo.class);
            dynamicCommentPageVo.setCommentTime(dynamicComment.getCreateTime());
            User user = userMapper.selectById(dynamicComment.getCommentUserUuid());
            dynamicCommentPageVo.setCommentUserAvatar(user.getAvatar());
            dynamicCommentPageVo.setCommentUserNickName(user.getNickName());
            // 判断该评论下是否还有儿子
            dynamicCommentPageVo.setHasChildren(
                dynamicCommentMapper.hasChildren(dynamicComment.getUuid()));
            // 查询被回复用户
            User repliedUser = userMapper.selectById(dynamicComment.getRepliedUserUuid());
            dynamicCommentPageVo.setRepliedNickName(repliedUser.getNickName());
            return dynamicCommentPageVo;
        }).collect(Collectors.toList());
        dynamicCommentPageVoIPage.setRecords(dynamicCommentPageVos);
        dynamicCommentPageVoIPage.setTotal(dynamicCommentIPage.getTotal());
        dynamicCommentPageVoIPage.setPages(dynamicCommentIPage.getPages());
        dynamicCommentPageVoIPage.setSize(dynamicCommentIPage.getSize());
        return dynamicCommentPageVoIPage;
    }

    /**
     * 校验数据真实性
     *
     * @param dynamicCommentAddBo
     */
    private void checkData(DynamicCommentAddBo dynamicCommentAddBo) {
        Dynamic dynamic = dynamicMapper.findById(dynamicCommentAddBo.getDynamicUuid())
            .orElseThrow(() -> new BusinessException("动态不存在"));
        if (!dynamic.getStatus().equals(DynamicStatus.PASSED)) {
            throw new BusinessException("动态未通过或者未审核");
        }
        User user = userMapper.findById(dynamicCommentAddBo.getRepliedUserUuid())
            .orElseThrow(() -> new BusinessException("被回复用户不存在"));
        if (!user.getIsSetBasicMessage()) {
            throw new BusinessException("被回复用户未设置基本信息，不能回复");
        }
        if (user.getDisabled()) {
            throw new BusinessException("被回复用户已被禁用，不能回复");
        }
    }
}
